<<<<<<< HEAD
from flask import g, jsonify
from flask import abort
from flask import current_app
from flask import request
from flask import session

from info import constants, db
from info.models import User, News, Comment
=======
from flask import g
from flask import abort
from flask import current_app
from flask import session

from info import constants, db
from info.models import User, News
>>>>>>> d487a945d3203647ec6decb47c923f198c6df23a
from info.utils.common import user_login_data
from . import news_detail_blu
from flask import render_template


@news_detail_blu.route("/<int:news_id>")
@user_login_data
def news_detail(news_id):
    # 获取用户登录信息
    user = g.user

<<<<<<< HEAD

=======
>>>>>>> d487a945d3203647ec6decb47c923f198c6df23a
    # 展示点击排行的新闻标题
    # 查询点击量在前n位的新闻
    try:
        news_click = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)

    # 查询新闻内容用作展示，查询出错和不存在都抛出404异常
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        abort(404)

    if not news:
        abort(404)

<<<<<<< HEAD
    # 点击量+1
=======
>>>>>>> d487a945d3203647ec6decb47c923f198c6df23a
    news.clicks += 1
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)

<<<<<<< HEAD
# 5.收藏和已收藏按钮的展示逻辑
#     明确需求：
#     在显示详情页的时候，需要知道
#     用户收藏了这个新闻没有，收藏了，显示取消收藏，没收藏 / 没登录，都显示收藏按钮
# 所以如果用户收藏了，要告诉前端， 应该展示取消收藏按钮(传一个布尔值到详情页模板)
    is_collected = False  # 定义这个变量来表示用户是否收藏当前新闻
    # if 用户登录了:
    #     if  用户收藏了这边新闻:
    #         is_collected = True
    if user:
        if news in user.collection_news: # user.collection_news 来拿到这个user用户所收藏的所有新闻（列表，每一个元素是News的对象）
            is_collected = True


    # 在加载详情页面的时候，也要查询这篇新闻下的所有的评论， 传到模板
    try:
        comments = Comment.query.filter(Comment.news_id == news.id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)

    comments_list = []
    for i in comments:
        comments_list.append(i.to_dict())


    # 将用户的点在评论列表传到模板中,为了明确某条评论有没有被用户点赞
    user_like_comments = []
    if user:
        for i in user.like_comments:  # user.like_comments 来获取 用户点赞过的所有评论
            user_like_comments.append(i.to_dict())

    # 获取这篇新闻的作者
    author = news.user  # news.user  获取这篇新闻的作者对象


    data = {
        "user": user.to_dict() if user else None,  # 如果user存在就返回user.to_dict(),如果不存在就返回None
        "news_click": news_click,
        "news": news.to_dict(),
        "is_collected": is_collected,
        "comments": comments_list,
        "user_like_comments": user_like_comments,
        "author": author.to_dict()
    }

    return render_template('news/detail.html', data=data)


@news_detail_blu.route("/news_collect", methods=["POST"])
@user_login_data
def news_collect():
    #需求：前端点击按钮后端执行收藏或者取消收藏的处理
    #需要传参数？
    # 1、对哪一篇新闻进行收藏要告诉服务器， 传新闻id
    #2、还要告诉服务器执行的是收藏还是取消收藏  action
    #注意：
    #用户 与 收藏新闻  多对多关系(一个用户可以收藏多条新闻，一条新闻可以被多用户收藏)
    #数据表info_user_collection 记录了用户 与 收藏新闻 的关系

    # 步骤分析：
    # 1、获取登录用户信息（用户没有登录，不允许收藏，直接return）
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
    # 2、接收参数(news_id，action为collect表示要执行收藏，也可以是cancel_collect表示要执行取消收藏)
    data_dict = request.json  # post请求用json
    news_id = data_dict.get("news_id")
    action = data_dict.get("action")
    # 3、判空
    if not all([news_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参1数错误")
    if action not in ("collect", "cancel_collect"):
        return jsonify(errno=RET.PARAMERR, errmsg="参2数错误")
    # 4、查询新闻，并判断是否存在
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询数据失败")

    if not news:
        return jsonify(errno=RET.NODATA, errmsg="新闻不存在")
    # 5、收藏或者取消收藏
    if action == "collect":
        # 收藏新闻
        # flask操作模型属性的时候，可以使用列表的操作来完成数据的追加和移除
        user.collection_news.append(news)
    else:
        user.collection_news.remove(news)

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="数据库操作失败")
    # 6、返回成功的响应
    return jsonify(errno=RET.OK, errmsg="操作成功")



# 八、评论新闻后端逻辑实现
    # 明确：
    # 评论新闻和回复别人的评论是一样的，处理的请求写在一个视图函数内
    # 参数分析：
    # 评论新闻需要传的参数：新闻id和评论内容即news_id、comment
    # 回复别人的评论需要传的参数： 新闻id和评论内容、还有回复的那条评论的id即news_id、comment、parent_id
from info.utils.response_code import RET
@news_detail_blu.route("/news_comment", methods=["POST"])
@user_login_data
def news_comment():
    # 步骤分析：
    # 1、获取登录用户信息
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
    # 2、接收参数
    data_dict = request.json
    news_id = data_dict.get("news_id")
    comment_str = data_dict.get("comment")
    parent_id = data_dict.get("parent_id")
    # 3、判空
    if not all([news_id, comment_str]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")
    # 4、查询新闻，并判断是否存在
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询数据失败")

    if not news:
        return jsonify(errno=RET.NODATA, errmsg="该新闻不存在")
    # 5、初始化一个评论模型，添加属性(如果有parent_id这个参数，也要添加这个属性)
    comment = Comment()
    comment.user_id = user.id
    comment.news_id = news_id
    comment.content = comment_str
    if parent_id:
        """如果是回复评论，则需要添加parent_id"""
        comment.parent_id = parent_id
    # 6、添加到数据库
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="保存评论数据失败")
    # 7、返回成功的响应（并把这个评论模型对象转成字典返回给前端，前端需要展示评论相关数据）
    return  jsonify(errno=RET.OK, errmsg="发表评论成功", data =comment.to_dict() ) # data=comment.to_dict() 为了前段ajax回调函数中使用这条评论的相关数据的展示


@news_detail_blu.route("/comment_like", methods=["POST"])
@user_login_data
def comment_like():
    # 1、获取登录用户信息
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    # 2、获取请求参数、判空  （评论id和action）
    data_dict = request.json
    comment_id = data_dict.get("comment_id")
    action = data_dict.get("action")

    if not all([comment_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    if action not in ("add", "remove"):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    # 3、查询评论并且判断评论是否存在
    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询数据失败")

    if not comment:
        return jsonify(errno=RET.NODATA, errmsg="评论不存在")

    # 4、根据action的值进行添加和删除(点赞 / 取消点赞成功以后，增加 /减少评论的点赞数量comment.like_count)
    if action == "add":
        user.like_comments.append(comment)
        # 点赞成功以后，添加评论的点赞数量
        comment.like_count += 1
    if action == "remove":
        user.like_comments.remove(comment)
        # 点赞取消以后，删减评论的点赞数量
        comment.like_count -= 1

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="操作失败")
    # 5、返回操作成功
    return jsonify(errno=RET.OK, errmsg="操作成功")

=======
    data = {
        "user": user.to_dict() if user else None,  # 如果user存在就返回user.to_dict(),如果不存在就返回None
        "news_click": news_click,
        "news": news.to_dict()
    }

    return render_template('detail.html', data=data)
>>>>>>> d487a945d3203647ec6decb47c923f198c6df23a
